<?php
/**
 * Created by PhpStorm.
 * User: jacob
 * Date: 18-10-15
 * Time: 上午11:04
 */
namespace DB\Home;

use Common\Logger;
use DB\MongoDefault;
use MongoDB\BSON\ObjectId;
use MongoDB\Driver\BulkWrite;

/**
 * JsonSerializable 如果属性私有，需要实现这个接口
 * Class AccountUserInfo
 * @package Db\Home
 */
class AccountUserInfo {
  public $_id;
  public $name;
  public $password;
  public $phone;
  public $email;
  public $nickname;
  public $create_at;
  public $update_at;

  public function toArray():array {
    $obj = json_decode(json_encode($this),true);
    return array_filter($obj,function ($k,$v){
      return $k != null;
    },ARRAY_FILTER_USE_BOTH);
  }
}

class AccountUser extends MongoDefault{
  const ID = "_id";
  const Email = "email";

  public function __construct(string $id = "") {
    parent::__construct("AccountUser", \MongoConfig::DBNAME);
    $this->id = $id;
  }

  /**
   * 插入数据
   * @param AccountUserInfo $info
   * @return null|string
   */
  public function insert(AccountUserInfo $info):?string {
    $manager = self::getInstance();
    $bulk = new BulkWrite();
    if (empty($info->create_at)){
      $info->create_at = (int)microtime(true)*1000;
    }
    $_id = $bulk->insert($info->toArray());

    try{
      $manager->executeBulkWrite($this->getNameSpace(),$bulk);
      return $_id;
    }catch (\Exception $e){
      echo $e->getMessage();
    }
    return null;
  }

  public function update(AccountUserInfo $info):bool {
    $manager = self::getInstance();
    $bulk = new BulkWrite();
    $bulk->update([AccountUser::ID => new ObjectId($this->id)],$info,['upsert' => true]);
    try{
      $manager->executeBulkWrite($this->getNameSpace(),$bulk);
      return true;
    }catch (\Exception $e){
      Logger::getInstance()->info("update error",$e);
    }
    return false;
  }

  /**
   * 获取成员对象
   * @param AccountUserInfo $info
   * @return bool
   */
  public function getInfo(AccountUserInfo $info):bool {
    $filter = [
      self::ID => new ObjectId($this->id)
    ];
    $result = self::getMany($filter)->toArray();
    if (count($result) == 0) return false;
    foreach ($result[0] as $key => $value){
      $info->{$key} = $value;
    }
    return true;
  }

  /**
   * 初始化密码明文
   * @param string $email
   * @return string
   */
  public function initPwd(string $email):string {
    return (string) crc32($email);
  }

  /**
   * 加密密码
   * @param string $password
   * @return string
   */
  public function encryPassword(string $password):string {
    return password_hash(md5($password),PASSWORD_BCRYPT,["cost" => 12]);
  }

  /**
   * 验证邮箱是否唯一
   * @param string $email
   * @return  bool
   */
  public function verifyEmail(string $email):bool {
    $filter = [
      AccountUser::Email => $email
    ];
    $options = [
      "projection" => [
        AccountUser::ID => 1
      ],
      "limit" => 1
    ];
    $result = $this->getMany($filter,$options)->toArray();
    if (count($result) == 0){
      return true;
    }
    return false;
  }

  /**
   * 通过Email查询用户信息
   * @param string $email
   * @return bool
   */
  public function buildByEmail(string $email):bool {
    $filter = [
      AccountUser::Email => $email
    ];
    $options = [
      "projection" => [
        AccountUser::ID => 1
      ],
      "limit" => 1
    ];
    $result = $this->getMany($filter,$options)->toArray();
    if (count($result) == 0) return false;
    $this->id = $result[0]->{self::ID};
    return true;
  }

  /**
   * 验证密码是否正确
   * @param string $password
   * @return bool
   */
  public function validatePwd(string $password):bool {
    $info = new AccountUserInfo();
    if(!$this->getInfo($info)) return false;
    if(password_verify(md5($password),$info->password)){
      return true;
    }
    return false;
  }

  public function getId(){
    return $this->id;
  }

  private $id;
}